# encoding=utf-8

import os
import json
import socket
import time
import logging
import subprocess
import socketserver

from conf import modules
from module import ModuleInterface
# from CarService import CarService
# from SteerService import SteerService
# from Led import SteerLedService
from socketserver import DatagramRequestHandler


logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')


class Engine(DatagramRequestHandler):
    modules_interface = dict()

    @classmethod
    def module_pid(cls, name):
        cmd = "ps -ef | grep %s | grep -v 'grep' | awk '{print $2}'" % name
        code, text = subprocess.getstatusoutput(cmd)
        if code == 0:
            try:
                return int(text)
            except Exception as e:
                return -1
        return 0

    @classmethod
    def fire(cls):
        # 启动所有模块，模块都提供了run接口
        for module in modules:
            pid = Engine.module_pid(module["name"])
            if pid > 0:
                logging.info("module %s already started as pid %d" % (module["name"], pid))
                continue

            logging.info("try start %s ..." % module["name"])
            cwd = os.getcwd()
            if module["type"] == "python":
                cmd = "cd %s && nohup python3 %s.py %d > /dev/null 2>&1 &" % (cwd, module["name"], module["udp-port"])
            else:
                 cmd = "cd %s && nohup ./%s %d > /dev/null 2>&1 &" % (cwd, module["name"], module["udp-port"])
            os.system(cmd)

            pid = Engine.module_pid(module["name"])
            if pid > 0:
                logging.info("%s started as pid %d " % (module["name"], pid))
            else:
                logging.warning("module %s status error" % module["name"])

    @classmethod
    def run(cls):
        server = socketserver.ThreadingUDPServer(('0.0.0.0', 8000), Engine)
        logging.info("engine started...")
        server.serve_forever()

    def handle(self):
        # 收到的都是json格式
        #{
        #   "action": "start / stop",
        #   "time": xx
        # }
        request = self.rfile.read()
        req_body = json.loads(request)
        print(req_body)
        action = req_body.get("action", "stop")
        if action in ["forward", "backward", "left", "right", "stop"]:
            ModuleInterface.call("CarService", request)
        elif action in ["turn-left-steer", "turn-right-steer"]:
            ModuleInterface.call("SteerService", request)
        elif action in ["turn-on-light", "flash-light"]:
            ModuleInterface.call("Led", request)


if __name__ == '__main__':
    Engine.fire()
    Engine.run()

